package com.glsc.ngateway.platform.service.system;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.glsc.ngateway.common.api.common.enums.Constant;
import com.glsc.ngateway.common.api.common.enums.DictConstant;
import com.glsc.ngateway.common.api.common.ex.GatewayException;
import com.glsc.ngateway.common.api.flowable.feign.IFeignFlowableService;
import com.glsc.ngateway.common.api.ldap.dto.LdapEhrDeptDto;
import com.glsc.ngateway.common.api.ldap.dto.LdapEhrDeptSearchDto;
import com.glsc.ngateway.common.api.ldap.dto.LdapEhrEmpDto;
import com.glsc.ngateway.common.api.ldap.feign.IFeignLdapService;
import com.glsc.ngateway.common.api.ldap.resp.AppEhrResponse;
import com.glsc.ngateway.common.api.ldap.resp.LdapResponse;
import com.glsc.ngateway.common.api.oaflow.dto.SystemFlowRelationResultDto;
import com.glsc.ngateway.common.api.oaflow.dto.SystemFlowStatisticsSearchParamDto;
import com.glsc.ngateway.common.api.oaflow.dto.VITSystemOAFlowResourceDto;
import com.glsc.ngateway.common.api.oaflow.dto.XinYiParamDto;
import com.glsc.ngateway.common.api.oaflow.dto.oaflow.SystemFlowStatisticsDto;
import com.glsc.ngateway.common.api.oaflow.dto.param.ParamFlowSearchDto;
import com.glsc.ngateway.common.api.oaflow.feign.IFeignOaFlowService;
import com.glsc.ngateway.common.api.oaflow.resp.OaflowResponse;
import com.glsc.ngateway.common.api.platform.dto.system.ParamSystemMainDto;
import com.glsc.ngateway.common.api.platform.dto.system.SystemMainDto;
import com.glsc.ngateway.common.api.platform.dto.user.PlatformUserDto;
import com.glsc.ngateway.common.api.platform.resp.PlatformResponse;
import com.glsc.ngateway.common.base.converter.platform.SystemFlowConverter;
import com.glsc.ngateway.common.base.converter.platform.SystemMainConverter;
import com.glsc.ngateway.common.base.domain.mysql.gateway.ldap.LdapEhrDept;
import com.glsc.ngateway.common.base.domain.mysql.gateway.other.IpSystemCode;
import com.glsc.ngateway.common.base.domain.mysql.gateway.platform.Appendix;
import com.glsc.ngateway.common.base.domain.mysql.gateway.platform.flow.FlowFormSystemNameApply;
import com.glsc.ngateway.common.base.domain.mysql.gateway.platform.flow.FlowFormSystemNameModify;
import com.glsc.ngateway.common.base.domain.mysql.gateway.system.*;
import com.glsc.ngateway.common.base.enums.SystemMemberTypeEnum;
import com.glsc.ngateway.common.base.exception.PlatformException;
import com.glsc.ngateway.common.base.repo.mysql.gateway.platform.AppendixRepo;
import com.glsc.ngateway.common.base.repo.mysql.gateway.platform.FlowFormSystemNameApplyRepo;
import com.glsc.ngateway.common.base.repo.mysql.gateway.platform.FlowFormSystemNameModifyRepo;
import com.glsc.ngateway.common.base.repo.mysql.gateway.platform.system.*;
import com.glsc.ngateway.platform.controller.system.SystemMemberController;
import com.glsc.ngateway.platform.service.MailService;
import com.glsc.ngateway.platform.service.SystemConfigService;
import com.glsc.ngateway.platform.service.UserService;
import com.glsc.ngateway.platform.service.it.DictionaryService;
import com.glsc.ngateway.platform.service.sequenceproduce.SequenceProducer;
import com.glsc.ngateway.platform.service.sequenceproduce.context.SystemAddSeqContext;
import com.glsc.ngateway.platform.utils.SpecificationUtil;
import com.glsc.ngateway.platform.utils.report.ExportFileEnum;
import com.glsc.ngateway.platform.utils.report.ExportFileUtil;
import com.glsc.ngateway.platform.vo.SystemFlowStatisticsVo;
import com.glsc.ngateway.platform.vo.converter.SystemFlowStatisticsConverter;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.logging.log4j.util.Strings;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Nullable;
import javax.annotation.Resource;
import java.io.IOException;
import java.time.LocalDate;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;


@Service
public class SystemMainService {

    Logger logger = LoggerFactory.getLogger(SystemMainService.class);

    @Autowired
    private UserService userService;

    @Resource
    private SystemMainRepository systemMainRepository;
    @Resource
    private SystemMainLogRepository systemMainLogRepository;
    @Resource
    private SystemMemberRepository systemMemberRepository;
    @Resource
    private SystemDocRepository systemDocRepository;
    @Resource
    private SystemDepartmentRepository systemDepartmentRepository;
    @Resource
    private SystemGroupRepository systemGroupRepository;
    @Resource
    private SystemVendorInfoRepository systemVendorInfoRepository;

    @Resource
    private IFeignLdapService iFeignLdapService;

    @Resource
    private DictionaryService dictionaryService;

    @Resource
    private IFeignFlowableService feignDemandService;

    @Resource
    private IFeignOaFlowService feignOaFlowService;
    @Resource
    private SystemVendorContractRelationRepository systemVendorContractRelationRepository;

    @Resource
    private SystemMainContactRepository systemMainContactRepository;

    @Resource
    private FlowFormSystemNameApplyRepo flowFormSystemNameApplyRepo;
    @Resource
    private FlowFormSystemNameModifyRepo flowFormSystemNameModifyRepo;

    @Resource
    private SystemConfigService systemConfigService;

    @Resource
    private IPSystemCodeRepository iPSystemCodeRepository;

    @Resource
    private AppendixRepo appendixRepo;

    @Resource
    private MailService mailService;

    @Transactional
    public SystemAddOrUpdateContext addOrUpdate(SystemMain systemMain, String userAccount) {
        SystemAddOrUpdateContext sysContext = SystemAddOrUpdateContext.builder().newSystem(systemMain).build();
        SystemMainLog systemMainLog = new SystemMainLog();
        int addOrUpdateFlag = 0;
        if (StrUtil.isNotEmpty(systemMain.getSystemClassNo())) {
            //修改
            systemMainLog.setLogFlag(DictConstant.UPDATE);
            sysContext.setType(DictConstant.UPDATE);
            addOrUpdateFlag = 2;
            sysContext.setOldSystem(BeanUtil.copyProperties(this.systemMainRepository.findBySystemClassNo(systemMain.getSystemClassNo()), SystemMain.class));
        } else {
            //新增
            systemMainLog.setLogFlag(DictConstant.ADD);
            sysContext.setType(DictConstant.ADD);
            //自动生成编号
            SystemAddSeqContext context = SystemAddSeqContext.builder()
                    .mainClass(systemMain.getMainClass())
                    .systemClass(systemMain.getSystemClass())
                    .build();
            SequenceProducer.produce(context);
            systemMain.setSystemClassNo(context.getRes());
            addOrUpdateFlag = 1;
        }
        systemMainRepository.save(systemMain);
        BeanUtil.copyProperties(systemMain, systemMainLog);
        systemMainLog.setLogJson(JSON.toJSONString(systemMain));
        systemMainLog.setUserAccount(userAccount);
        systemMainLogRepository.save(systemMainLog);

        if (addOrUpdateFlag == 2) {
            //修改关系，先删除，其他就正常新增
            //项目经理
            List<SystemMember> beanList = systemMemberRepository.queryAllByDeletedAndOpId(DictConstant.NO_DELETE, systemMain.getOpId());
            if (CollectionUtil.isNotEmpty(beanList)) {
                //只处理 项目经理 系统管理员 运维管理员
                beanList.forEach(bean -> {
                    if (StringUtils.isNotBlank(bean.getMemberType())) {
                        if (bean.getMemberType().equals("1") || bean.getMemberType().equals("2") || bean.getMemberType().equals("3")) {
                            bean.setDeleted(DictConstant.DELETED);
                        }
                    }
                });
            }
            systemMemberRepository.saveAll(beanList);
            //对口部门
            systemDepartmentRepository.deleteByOpId(systemMain.getOpId());
            //团队
            systemGroupRepository.deleteByOpId(systemMain.getOpId());
            //联系人
            systemVendorContractRelationRepository.deleteByVendorIdAndContactType(systemMain.getOpId(), DictConstant.CONTRACT_SYSTEM);
//            //供应商
//            systemVendorRelationRepository.deleteByOpId(systemMain.getOpId());
            systemMainContactRepository.deleteByOpId(systemMain.getOpId());
            //附件
            systemDocRepository.deleteByOpId(systemMain.getOpId());
        }
        addRelation(systemMain);
        return sysContext;
    }

    public String findProgramBySysid(String systemId) {
        return systemMainRepository.findAllBySystemIdIn(List.of(systemId)).stream().findFirst().map(SystemMain::getProgramId).orElse(Strings.EMPTY);
    }

    public String findNameByGiteeId(Integer programId) {
        if (Objects.isNull(programId)) {
            return null;
        }
        return Optional.ofNullable(systemMainRepository.findByProgramId(String.valueOf(programId))).map(SystemMain::getOpName).orElse(null);
    }

    /**
     * 通过oa流程信息更新系统清单状态
     * @param oaFlowInfo
     */
    @Transactional
    public void updateInfoByOaInfo(String oaFlowInfo) {
        JSONObject retJSONObject = JSONObject.parseObject(oaFlowInfo);
        //查询OA表单数据字段
        JSONArray dataJson = retJSONObject.getJSONArray("data");
        JSONObject jsonObject = dataJson.getJSONObject(0);
        JSONObject flowInfosJSONObject = jsonObject.getJSONObject("flowInfos");//表单个性化字段信息
        String lxCode = flowInfosJSONObject.getString("LXCode") == null ?"" : flowInfosJSONObject.getString("LXCode");
        String lx = flowInfosJSONObject.getString("LX") == null ? "" :flowInfosJSONObject.getString("LX");
        String systemCode = flowInfosJSONObject.getString("XTMCX") == null ? "":flowInfosJSONObject.getString("XTMCX");
        if ("3".equals(lxCode) && lx.contains("下线")){
            SystemMain systemInfo = findBySystemClassNo(systemCode);
            systemInfo.setStatus(lxCode);
            //防止事务干扰
            SystemMain systemInfoNew = JSONObject.parseObject(JSON.toJSONString(systemInfo),SystemMain.class);
            addOrUpdate(systemInfoNew,"OA同步");
        } else {
            if ("3".equals(lxCode) || lx.contains("下线")){
                mailService.sendMailToAdmin("oa系统状态编码错误",oaFlowInfo);
            }
        }
    }

    /**
     * 新增或修改系统上下文
     */
    @Data
    @Builder
    @AllArgsConstructor
    @NoArgsConstructor
    public static class SystemAddOrUpdateContext {
        @Nullable
        SystemMain oldSystem;
        SystemMain newSystem;
        Integer type;
    }

    public SystemMain findBySystemClassNo(String systemClassNo) {
        SystemMain systemMain = systemMainRepository.findBySystemClassNo(systemClassNo);
        //填充其他信息
        if (Objects.nonNull(systemMain)) {
            fillOtheInfo(systemMain);
        }
        return systemMain;
    }

    /**
     * 新增各类关系
     *
     * @param systemMain
     */
    @Transactional
    private void addRelation(SystemMain systemMain) {
        //维护项目经理关系
        List<String> memberManager = systemMain.getMemberManager();
        if (CollectionUtil.isNotEmpty(memberManager)) {
            List<SystemMember> memberList = memberManager.stream().filter(m -> m != null).map(key -> {
                PlatformUserDto user = userService.getUsrUrls(key);
                SystemMember m = new SystemMember();
                m.setMemberAccount(key);
                m.setMemberName(user.getName());
                m.setOpId(systemMain.getOpId());
                m.setDeleted(DictConstant.NO_DELETE);
                m.setMemberType(SystemMemberTypeEnum.PROJECT_MANAGER.getCode());
                m.setStatus(DictConstant.MEMBER_STATUS_NORMAL);
                return m;
            }).collect(Collectors.toList());
            systemMemberRepository.saveAll(memberList);
        }
        if (CollectionUtil.isNotEmpty(systemMain.getSystemManager())) {
            List<SystemMember> memberList = systemMain.getSystemManager().stream().filter(m -> m != null).map(key -> {
                PlatformUserDto user = userService.getUsrUrls(key);
                SystemMember m = new SystemMember();
                m.setMemberAccount(key);
                m.setMemberName(user.getName());
                m.setOpId(systemMain.getOpId());
                m.setDeleted(DictConstant.NO_DELETE);
                m.setMemberType(SystemMemberTypeEnum.SYSTEM_MANAGER.getCode());
                m.setStatus(DictConstant.MEMBER_STATUS_NORMAL);
                return m;
            }).collect(Collectors.toList());
            systemMemberRepository.saveAll(memberList);
        }
        if (CollectionUtil.isNotEmpty(systemMain.getOpsManager())) {
            List<SystemMember> memberList = systemMain.getOpsManager().stream().filter(m -> m != null).map(key -> {
                PlatformUserDto user = userService.getUsrUrls(key);
                SystemMember m = new SystemMember();
                m.setMemberAccount(key);
                m.setMemberName(user.getName());
                m.setOpId(systemMain.getOpId());
                m.setDeleted(DictConstant.NO_DELETE);
                m.setMemberType(SystemMemberTypeEnum.OPS_MANAGER.getCode());
                m.setStatus(DictConstant.MEMBER_STATUS_NORMAL);
                return m;
            }).collect(Collectors.toList());
            systemMemberRepository.saveAll(memberList);
        }
        //业务对口部门
        List<String> businessDepartment = systemMain.getBusinessDepartment();
        if (CollectionUtil.isNotEmpty(businessDepartment)) {
            List<SystemDepartment> beanList = businessDepartment.stream().filter(m -> m != null).map(key -> {
                SystemDepartment m = new SystemDepartment();
                m.setDepartmentId(key);
                m.setOpId(systemMain.getOpId());
                return m;
            }).collect(Collectors.toList());
            systemDepartmentRepository.saveAll(beanList);
        }
        //所属团队
        List<String> opGroupId = systemMain.getOpGroupId();
        if (CollectionUtil.isNotEmpty(opGroupId)) {
            List<SystemGroup> beanList = opGroupId.stream().filter(m -> m != null).map(key -> {
                SystemGroup m = new SystemGroup();
                m.setGroupId(key);
                m.setOpId(systemMain.getOpId());
                return m;
            }).collect(Collectors.toList());
            systemGroupRepository.saveAll(beanList);
        }
        //联系人
        List<String> contractId = systemMain.getContactId();
        if (CollectionUtil.isNotEmpty(contractId)) {
            List<SystemVendorContractRelation> beanList = contractId.stream().filter(k -> k != null).map(key -> {
                SystemVendorContractRelation m = new SystemVendorContractRelation();
                m.setContactId(Integer.valueOf(key));
                m.setVendorId(systemMain.getOpId());
                m.setContactType(DictConstant.CONTRACT_SYSTEM);
                return m;
            }).collect(Collectors.toList());
            systemVendorContractRelationRepository.saveAll(beanList);
        }
        //手动联系人
        List<SystemMainContact> contactInfo = systemMain.getContactInfo();
        if (CollectionUtil.isNotEmpty(contactInfo)) {
            contactInfo.forEach(info -> {
                info.setOpId(systemMain.getOpId());
            });
            systemMainContactRepository.saveAll(contactInfo);
        }
        //附件
        SystemDoc systemDoc = systemMain.getSystemDoc();
        if (systemDoc != null && StrUtil.isNotEmpty(systemDoc.getDocIdList())) {
            systemDoc.setOpId(systemMain.getOpId());
            if (systemDoc.getYear() == null){
                systemDoc.setYear(LocalDate.now().getYear());
            }
            systemDocRepository.save(systemDoc);
        }

//        //供应商
//        List<String> opSupport = systemMain.getOpSupport();
//        if(CollectionUtil.isNotEmpty(opSupport)){
//            List<SystemVendorRelation> beanList = opSupport.stream().map(key ->{
//                SystemVendorRelation m = new SystemVendorRelation();
//                m.setVendorId(key);
//                m.setOpId(systemMain.getOpId());
//                return m;
//            }).collect(Collectors.toList());
//            systemVendorRelationRepository.saveAll(beanList);
//        }
    }

    public void delete(String id) {
//        不提供删除接口
//        SystemMain systemMain = systemMainRepository.findByOpId(id);
//        SystemMainLog systemMainLog = new SystemMainLog();
//        BeanUtil.copyProperties(systemMain,systemMainLog);
//
//        systemMainRepository.save(systemMain);
//        systemMainLogRepository.save(systemMainLog);
    }


    /**
     * 根据id查找系统信息
     *
     * @param opId
     * @return
     */
    public SystemMain findById(Integer opId) {
        Optional<SystemMain> optional = systemMainRepository.findById(opId);
        if (!optional.isPresent()) {
            return null;
        }
        SystemMain systemMain = optional.get();

        /*List<SystemMember> members = systemMemberRepository.findAll(Example.of(SystemMember.builder().opId(systemMain.getOpId()).deleted(0).build()));
        if (CollectionUtil.isNotEmpty(members)) {
            List<String> memManager = members.stream().filter(e -> e.getMemberType().equals(SystemMemberTypeEnum.PROJECT_MANAGER.getCode())).map(SystemMember::getMemberAccount).collect(Collectors.toList());
            systemMain.setMemberManager(CollectionUtil.isNotEmpty(memManager) ? memManager : Lists.newArrayList());
            List<String> systemManager = members.stream().filter(e -> e.getMemberType().equals(SystemMemberTypeEnum.SYSTEM_MANAGER.getCode())).map(SystemMember::getMemberAccount).collect(Collectors.toList());
            systemMain.setSystemManager(CollectionUtil.isNotEmpty(systemManager) ? systemManager : Lists.newArrayList());
            List<String> opsManager = members.stream().filter(e -> e.getMemberType().equals(SystemMemberTypeEnum.OPS_MANAGER.getCode())).map(SystemMember::getMemberAccount).collect(Collectors.toList());
            systemMain.setOpsManager(CollectionUtil.isNotEmpty(opsManager) ? opsManager : Lists.newArrayList());
            systemMain.setOpGroupId(Lists.newArrayList());

            List<SystemGroup> systemGroups = systemGroupRepository.findAll(Example.of(SystemGroup.builder().opId(opId).build()));
            if (CollectionUtil.isNotEmpty(systemGroups)) {
                systemMain.setOpGroupId(systemGroups.stream().map(SystemGroup::getGroupId).collect(Collectors.toList()));
            }
        }

        systemMain.setContactInfo(Lists.newArrayList());
        List<SystemMainContact> contacts = systemMainContactRepository.queryAllByOpId(opId);
        if (CollectionUtil.isNotEmpty(contacts)) {
            systemMain.setContactInfo(contacts);
        }

        int year = LocalDate.now().getYear();
        List<SystemDoc> docs = systemDocRepository.queryAllByOpIdAndYear(opId, year);
        if (CollectionUtil.isNotEmpty(docs)) {
            systemMain.setSystemDoc(docs.get(0));
        }
        systemMain.setOperateFlag(1);*/
        systemMain.setOperateFlag(1);
        systemMain = fillOtheInfo(systemMain);
        return systemMain;
    }

    public SystemMain findSimpleInfoById(Integer opId) {
        Optional<SystemMain> optional = systemMainRepository.findById(opId);
        if (!optional.isPresent()) {
            return null;
        }
        SystemMain systemMain = optional.get();
        return systemMain;
    }

    public Page<SystemMain> search(ParamSystemMainDto params) {
        Pageable pageable = PageRequest.of(params.getPageNo() - 1, params.getPageSize());
        String account = params.getMemberAccount();//登录人账号
        if (StringUtils.isNotEmpty(account)) {
            List<Integer> opIdList = systemMainRepository.queryListByAuth(account).stream().map(h -> h.getOpId()).collect(Collectors.toList());
            params.setOpIdAuthList(opIdList);
        }
        if (CollectionUtils.isNotEmpty(params.getMemberManager()) || CollectionUtils.isNotEmpty(params.getSystemManager()) || CollectionUtils.isNotEmpty(params.getOpsManager())) {
            Set<Integer> allMemberFilterOpIdList = null;
            if (CollectionUtils.isNotEmpty(params.getMemberManager())) {
                allMemberFilterOpIdList = systemMemberRepository.findAllByMemberTypeAndMemberAccountInAndDeleted(SystemMemberTypeEnum.PROJECT_MANAGER.getCode(), params.getMemberManager(), DictConstant.NO_DELETE)
                        .stream().map(SystemMember::getOpId).collect(Collectors.toSet());
            }
            if (CollectionUtils.isNotEmpty(params.getSystemManager() )) {
                Set<Integer> systemMembers = systemMemberRepository.findAllByMemberTypeAndMemberAccountInAndDeleted(SystemMemberTypeEnum.SYSTEM_MANAGER.getCode(), params.getSystemManager(), DictConstant.NO_DELETE)
                        .stream().map(SystemMember::getOpId).collect(Collectors.toSet());
                if (Objects.isNull(allMemberFilterOpIdList)) {
                    allMemberFilterOpIdList = systemMembers;
                } else {
                    allMemberFilterOpIdList.retainAll(systemMembers);
                }
            }
            if (CollectionUtils.isNotEmpty(params.getOpsManager())) {
                Set<Integer> opsManagers = systemMemberRepository.findAllByMemberTypeAndMemberAccountInAndDeleted(SystemMemberTypeEnum.OPS_MANAGER.getCode(), params.getOpsManager(), DictConstant.NO_DELETE)
                        .stream().map(SystemMember::getOpId).collect(Collectors.toSet());
                if (Objects.isNull(allMemberFilterOpIdList)) {
                    allMemberFilterOpIdList = opsManagers;
                } else {
                    allMemberFilterOpIdList.retainAll(opsManagers);
                }
            }
            if (CollectionUtils.isNotEmpty(allMemberFilterOpIdList)) {
                params.setOpIdList(new ArrayList<>(allMemberFilterOpIdList));
            } else {
                return Page.empty();
            }
        }
        Page<SystemMain> result = systemMainRepository.searchByParam(pageable, params);
        List<SystemMain> systemMains = result.getContent();
        if (CollectionUtil.isNotEmpty(systemMains)) {
            for (SystemMain systemMain : systemMains) {
                fillOtheInfo(systemMain);
            }
        }
        return result;
    }

    /**
     * 填充其他信息
     *
     * @param systemMain
     */
    private SystemMain fillOtheInfo(SystemMain systemMain) {
        //填充项目经理
        Integer opId = systemMain.getOpId();
        List<SystemMember> systemMebers = systemMemberRepository.queryAllByDeletedAndOpId(DictConstant.NO_DELETE, opId);
        if (CollectionUtil.isNotEmpty(systemMebers)) {
            Map<String, List<SystemMember>> map = systemMebers.stream().collect(Collectors.groupingBy(SystemMember::getMemberType));
            if (map.containsKey(SystemMemberTypeEnum.PROJECT_MANAGER.getCode())) {
                List<SystemMember> list = map.get(SystemMemberTypeEnum.PROJECT_MANAGER.getCode());
                systemMain.setMemberManager(list.stream().map(SystemMember::getMemberAccount).collect(Collectors.toList()));
                systemMain.setMemberManagerNameList(list.stream().map(SystemMember::getMemberName).collect(Collectors.toList()));
            }
            if (map.containsKey(SystemMemberTypeEnum.SYSTEM_MANAGER.getCode())) {
                List<SystemMember> list = map.get(SystemMemberTypeEnum.SYSTEM_MANAGER.getCode());
                systemMain.setSystemManager(list.stream().map(SystemMember::getMemberAccount).collect(Collectors.toList()));
                systemMain.setSystemManagerNameList(list.stream().map(SystemMember::getMemberName).collect(Collectors.toList()));
            }
            if (map.containsKey(SystemMemberTypeEnum.OPS_MANAGER.getCode())) {
                List<SystemMember> list = map.get(SystemMemberTypeEnum.OPS_MANAGER.getCode());
                systemMain.setOpsManager(list.stream().map(SystemMember::getMemberAccount).collect(Collectors.toList()));
                systemMain.setOpsManagerNameList(list.stream().map(SystemMember::getMemberName).collect(Collectors.toList()));
            }
        }
        //填充供应商
//                List<SystemVendorRelation> systemVendorRelation = systemVendorRelationRepository.queryAllByOpId(opId);
//                List<Integer> vendorId = systemVendorRelation.stream().filter(v->v.getVendorId()!= null).map(v-> Integer.valueOf(v.getVendorId())).collect(Collectors.toList());
//                List<String> vendorIdString = systemVendorRelation.stream().map(v-> v.getVendorId()).collect(Collectors.toList());
//                systemMain.setOpSupport(vendorIdString);
        //填充供应商名称
        if (systemMain.getOpSupport() != null) {
            List<SystemVendorInfo> systemVendorInfos = systemVendorInfoRepository.findAllByIdIn(ImmutableList.of(systemMain.getOpSupport()));
            if (CollectionUtil.isNotEmpty(systemVendorInfos)) {
                systemMain.setOpSupportName(systemVendorInfos.get(0).getVendorName());
            }
        }

        //团队
        List<SystemGroup> groups = systemGroupRepository.queryAllByOpId(opId);
        systemMain.setOpGroupId(groups.stream().map(g -> g.getGroupId()).collect(Collectors.toList()));
        //所属部门
        List<SystemDepartment> departments = systemDepartmentRepository.queryAllByOpId(opId);
        systemMain.setBusinessDepartment(departments.stream().map(d -> d.getDepartmentId()).collect(Collectors.toList()));
        //联系人
        List<SystemVendorContractRelation> contractRelations = systemVendorContractRelationRepository.queryAllByVendorIdAndContactType(opId, DictConstant.CONTRACT_SYSTEM);
        systemMain.setContactId(contractRelations.stream().map(d -> d.getContactId().toString()).collect(Collectors.toList()));
        //手动联系人
        List<SystemMainContact> contractInfos = systemMainContactRepository.queryAllByOpId(opId);
        systemMain.setContactInfo(contractInfos);
        if (CollectionUtil.isNotEmpty(contractInfos)) {
            List<String> contactNames = contractInfos.stream().map(c -> c.getContactPerson()).collect(Collectors.toList());
            systemMain.setContactName(contactNames);
        }
        String config = systemConfigService.findConfigValueByCode("SYSTEM_MAIN_YEAR");
        int year = LocalDate.now().getYear();
        if (StrUtil.isNotEmpty(config)) {
            year = Integer.valueOf(config);
        }
        List<SystemDoc> docs = systemDocRepository.queryAllByOpIdAndYear(opId, year);
        if (CollectionUtil.isNotEmpty(docs) && StrUtil.isNotBlank(docs.get(0).getDocIdList())) {
            String[] docIds = docs.get(0).getDocIdList().split(",");
            List<Appendix> docList = new ArrayList<>();
            if (docIds != null && docIds.length > 0) {
                for (String docId : docIds) {
                    Appendix appendix = appendixRepo.findById(docId);
                    docList.add(appendix);
                }
                docs.get(0).setDocList(docList);
            }
            systemMain.setSystemDoc(docs.get(0));
        }
        if (CollectionUtil.isNotEmpty(docs) && StrUtil.isNotBlank(docs.get(0).getPdfIdList())) {
            String[] pdfIds = docs.get(0).getPdfIdList().split(",");
            List<Appendix> docList = new ArrayList<>();
            if (pdfIds != null && pdfIds.length > 0) {
                for (String docId : pdfIds) {
                    Appendix appendix = appendixRepo.findById(docId);
                    docList.add(appendix);
                }
                docs.get(0).setPdfList(docList);
            }
            systemMain.setSystemDoc(docs.get(0));
        }

        if (CollectionUtil.isEmpty(systemMain.getOpGroupId())) {
            systemMain.setOpGroupId(Lists.newArrayList());
        }
        if (CollectionUtil.isEmpty(systemMain.getMemberManager())) {
            systemMain.setMemberManager(Lists.newArrayList());
        }
        if (CollectionUtil.isEmpty(systemMain.getSystemManager())) {
            systemMain.setSystemManager(Lists.newArrayList());
        }
        if (CollectionUtil.isEmpty(systemMain.getOpsManager())) {
            systemMain.setOpsManager(Lists.newArrayList());
        }


        return systemMain;
    }

    public List<SystemMainLog> querySystemMainLog(Integer opId) {
        ParamSystemMainDto param = new ParamSystemMainDto();
        param.setOpId(opId);
        List<SystemMainLog> resultOrign = systemMainLogRepository.searchByParam(param);
        List<SystemMainLog> result = CollectionUtil.newCopyOnWriteArrayList(resultOrign);
        if (CollectionUtil.isNotEmpty(result) && result.size() == 1) {
            resultOrign.get(0).setLogSummary("初始化");
        } else if (result.size() > 1) {
            for (int i = 0; i < result.size() - 1; i++) {
                String summary = compare(result.get(i + 1), result.get(i));
                resultOrign.get(i).setLogSummary(summary);
            }
            resultOrign.get(result.size() - 1).setLogSummary("初始化");
        }
        return resultOrign.stream().filter(e -> StrUtil.isNotEmpty(e.getLogSummary())).collect(Collectors.toList());
    }

    private String compare(SystemMainLog systemMainLogOrign, SystemMainLog systemMainLog1Orgin) {
        SystemMainLog systemMainLog = new SystemMainLog();
        SystemMainLog systemMainLog1 = new SystemMainLog();
        BeanUtil.copyProperties(systemMainLogOrign, systemMainLog);
        BeanUtil.copyProperties(systemMainLog1Orgin, systemMainLog1);
        String summary = "";
        if (!Objects.equals(systemMainLog.getOpName(), systemMainLog1.getOpName())) {
            summary += "系统名称由" + systemMainLog.getOpName() + "变更为" + systemMainLog1.getOpName() + ";";
        }
        if (!Objects.equals(systemMainLog.getOpBuild(), systemMainLog1.getOpBuild())) {
            Map<String, String> dictMap = dictionaryService.getItDictDataRepo("system_build_type");
            summary += "系统建设方式由" + dictMap.get(systemMainLog.getOpBuild().toString()) + "变更为" + dictMap.get(systemMainLog1.getOpBuild().toString()) + ";";
        }
        if (!Objects.equals(systemMainLog.getOpSupport(), systemMainLog1.getOpSupport())) {
            List<SystemVendorInfo> vendor = new ArrayList<>();
            List<SystemVendorInfo> vendor1 = new ArrayList<>();
            if (StrUtil.isNotEmpty(systemMainLog.getOpSupport())) {
                vendor = systemVendorInfoRepository.findAllByIdIn(ImmutableList.of(Integer.valueOf(systemMainLog.getOpSupport())));
            } else {
                vendor.add(new SystemVendorInfo());
            }
            if (StrUtil.isNotEmpty(systemMainLog1.getOpSupport())) {
                vendor1 = systemVendorInfoRepository.findAllByIdIn(ImmutableList.of(Integer.valueOf(systemMainLog1.getOpSupport())));
            } else {
                vendor1.add(new SystemVendorInfo());
            }
            summary += "系统供应商由" + vendor.get(0).getVendorName() + "变更为" + vendor1.get(0).getVendorName() + ";";
        }
        if (!Objects.equals(systemMainLog.getSystemSummary(), systemMainLog1.getSystemSummary())) {
            summary += "系统功能描述由" + systemMainLog.getSystemSummary() + "变更为" + systemMainLog1.getSystemSummary() + ";";
        }

        if (!Objects.equals(systemMainLog.getStatus(), systemMainLog1.getStatus())) {
            Map<String, String> dictMap = dictionaryService.getItDictDataRepo("system_status");
            summary += "系统状态由" + dictMap.get(systemMainLog.getStatus().toString()) + "变更为" + dictMap.get(systemMainLog1.getStatus().toString()) + ";";
        }

        //获取所有部门
        AppEhrResponse<List<LdapEhrDeptDto>> depts = iFeignLdapService.getAllDept();
        List<LdapEhrDeptDto> deptinfoEntityList = Objects.nonNull(depts) && CollectionUtil.isNotEmpty(depts.getData()) ? depts.getData() : Collections.EMPTY_LIST;
        Map<Integer, String> deptMap = deptinfoEntityList.stream().collect(Collectors.toMap(LdapEhrDeptDto::getDepid, LdapEhrDeptDto::getDtitle, (K1, K2) -> K2));
        //获取所有人员
        AppEhrResponse<List<LdapEhrEmpDto>> user = iFeignLdapService.getAllEmps();
        Map<String, String> finalEhrDeptMap = (Objects.isNull(user) || CollectionUtil.isEmpty(user.getData())) ? Collections.EMPTY_MAP :
                user.getData().stream().collect(Collectors.toMap(LdapEhrEmpDto::getBadge, LdapEhrEmpDto::getName, (v1, v2) -> v2));
        JSONObject log = JSONObject.parseObject(systemMainLog.getLogJson());
        JSONObject log1 = JSONObject.parseObject(systemMainLog1.getLogJson());
        //业务对口部门
        if (!Objects.equals(log.getString("businessDepartment"), log1.getString("businessDepartment"))) {
            List<String> businessDepartment = ImmutableList.of("空");
            if (log.getString("businessDepartment") != null && log.getJSONArray("businessDepartment").size() > 0) {
                businessDepartment = log.getJSONArray("businessDepartment").stream().filter(m -> m != null && !"null".equals(m)).map(d -> deptMap.get(Integer.valueOf(d.toString()))).collect(Collectors.toList());
            }
            List<String> businessDepartment1 = ImmutableList.of("空");
            if (log1.getString("businessDepartment") != null && log1.getJSONArray("businessDepartment").size() > 0) {
                businessDepartment1 = log1.getJSONArray("businessDepartment").stream().filter(m -> m != null && !"null".equals(m)).map(d -> deptMap.get(Integer.valueOf(d.toString()))).collect(Collectors.toList());
            }
            if (!businessDepartment.equals(businessDepartment1)) {
                summary += "业务对口部门由" + String.join(",", businessDepartment) + "变更为" + String.join(",", businessDepartment1) + ";";
            }
        }
        //隶属团队
        if (!Objects.equals(log.getString("opGroupId"), log1.getString("opGroupId"))) {
            List<String> businessDepartment = ImmutableList.of("空");
            if (log.getString("opGroupId") != null && log.getJSONArray("opGroupId").size() > 0) {
                businessDepartment = log.getJSONArray("opGroupId").stream().filter(m -> m != null && !"null".equals(m)).map(d -> deptMap.get(Integer.valueOf(d.toString()))).collect(Collectors.toList());
            }
            List<String> businessDepartment1 = ImmutableList.of("空");
            if (log1.getString("opGroupId") != null && log1.getJSONArray("opGroupId").size() > 0) {
                businessDepartment1 = log1.getJSONArray("opGroupId").stream().filter(m -> m != null && !"null".equals(m)).map(d -> deptMap.get(Integer.valueOf(d.toString()))).collect(Collectors.toList());
            }
            if (!businessDepartment.equals(businessDepartment1)) {
                summary += "隶属团队由" + String.join(",", businessDepartment) + "变更为" + String.join(",", businessDepartment1) + ";";
            }
        }
        //项目经理
        if (!Objects.equals(log.getString("memberManager"), log1.getString("memberManager"))) {
            List<String> businessDepartment = ImmutableList.of("空");
            if (log.getString("memberManager") != null && log.getJSONArray("memberManager").size() > 0) {
                businessDepartment = log.getJSONArray("memberManager").stream().filter(m -> m != null && !"null".equals(m)).map(d -> finalEhrDeptMap.get(d.toString())).collect(Collectors.toList());
            }
            List<String> businessDepartment1 = ImmutableList.of("空");
            if (log1.getString("memberManager") != null && log1.getJSONArray("memberManager").size() > 0) {
                businessDepartment1 = log1.getJSONArray("memberManager").stream().filter(m -> m != null && !"null".equals(m)).map(d -> finalEhrDeptMap.get(d.toString())).collect(Collectors.toList());
            }
            if (!businessDepartment.equals(businessDepartment1)) {
                summary += "项目经理由" + String.join(",", businessDepartment) + "变更为" + String.join(",", businessDepartment1) + ";";
            }
        }
        //项目经理
        if (!Objects.equals(log.getString("systemManager"), log1.getString("systemManager"))) {
            List<String> businessDepartment = ImmutableList.of("空");
            if (log.getString("systemManager") != null && log.getJSONArray("systemManager").size() > 0) {
                businessDepartment = log.getJSONArray("systemManager").stream().filter(m -> m != null && !"null".equals(m)).map(d -> finalEhrDeptMap.get(d.toString())).collect(Collectors.toList());
            }
            List<String> businessDepartment1 = ImmutableList.of("空");
            if (log1.getString("systemManager") != null && log1.getJSONArray("systemManager").size() > 0) {
                businessDepartment1 = log1.getJSONArray("systemManager").stream().filter(m -> m != null && !"null".equals(m)).map(d -> finalEhrDeptMap.get(d.toString())).collect(Collectors.toList());
            }
            if (!businessDepartment.equals(businessDepartment1)) {
                summary += "系统管理员由" + String.join(",", businessDepartment) + "变更为" + String.join(",", businessDepartment1) + ";";
            }
        }
        //项目经理
        if (!Objects.equals(log.getString("opsManager"), log1.getString("opsManager"))) {
            List<String> businessDepartment = ImmutableList.of("空");
            if (log.getString("opsManager") != null && log.getJSONArray("opsManager").size() > 0) {
                businessDepartment = log.getJSONArray("opsManager").stream().filter(m -> m != null && !"null".equals(m)).map(d -> finalEhrDeptMap.get(d.toString())).collect(Collectors.toList());
            }
            List<String> businessDepartment1 = ImmutableList.of("空");
            if (log1.getString("opsManager") != null && log1.getJSONArray("opsManager").size() > 0) {
                businessDepartment1 = log1.getJSONArray("opsManager").stream().filter(m -> m != null && !"null".equals(m)).map(d -> finalEhrDeptMap.get(d.toString())).collect(Collectors.toList());
            }
            if (!businessDepartment.equals(businessDepartment1)) {
                summary += "运维管理员由" + String.join(",", businessDepartment) + "变更为" + String.join(",", businessDepartment1) + ";";
            }
        }
        //归口管理部门
        if (!Objects.equals(systemMainLog.getBelongDeptId(), systemMainLog1.getBelongDeptId())) {
            if (systemMainLog.getBelongDeptId() != null && systemMainLog1.getBelongDeptId() != null) {
                summary += "归口管理部门由" + systemMainLog.getBelongDeptId() == null ? "空" : deptMap.get(Integer.valueOf(systemMainLog.getBelongDeptId())) + "变更为"
                        + systemMainLog1.getBelongDeptId() == null ? "空" : deptMap.get(Integer.valueOf(systemMainLog1.getBelongDeptId())) + ";";
            }
        }
        //手动联系人变更
        if (!Objects.equals(log.getString("contactInfo"), log1.getString("contactInfo"))) {
            List<SystemMainContact> businessDepartment = log.getObject("contactInfo", new TypeReference<List<SystemMainContact>>() {
            });
            List<SystemMainContact> businessDepartment1 = log1.getObject("contactInfo", new TypeReference<List<SystemMainContact>>() {
            });
            List<String> info = ImmutableList.of("空");
            if (businessDepartment != null && businessDepartment.size() > 0) {
                info = businessDepartment.stream().map(i -> i.getContactPerson()).collect(Collectors.toList());
            }
            List<String> info1 = ImmutableList.of("空");
            if (businessDepartment1 != null && businessDepartment1.size() > 0) {
                info1 = businessDepartment1.stream().map(i -> i.getContactPerson()).collect(Collectors.toList());
            }
            if (!info1.equals(info)) {
                summary += "联系人由" + String.join(",", info) + "变更为" + String.join(",", info1) + ";";
            }
        }
        summary = summary.replaceAll("null", "空");
        return summary;

    }

    /**
     * 获取建议人员
     *
     * @param bean
     * @return
     */
    public String advice(ParamSystemMainDto bean) {
        SystemAddSeqContext context = SystemAddSeqContext.builder()
                .mainClass(bean.getMainClass())
                .systemClass(bean.getSystemClass())
                .build();
        SequenceProducer.produce(context);
        return context.getRes();
    }

    @Cacheable(cacheNames = "queryAllSystem#6000")
    public List<SystemMain> queryAll() {
        List<SystemMain> systemMains = systemMainRepository.findAll();
        if (CollectionUtil.isNotEmpty(systemMains)) {
            for (SystemMain systemMain : systemMains) {
                fillOtheInfo(systemMain);
            }
        }
        return systemMains;
    }

    /**
     * 统计系统名称数量
     */
    public Integer countByOpName(String opName) {
        return systemMainRepository.countByOpName(opName);
    }

    /**
     * 通过系统名称查找
     */
    public SystemMain findByOpName(String opName) {
        return systemMainRepository.findByOpName(opName);
    }

    /**
     * 通过系统标识查找
     */
    @Cacheable(cacheNames = "findAllBySystemIdIn#60000")
    public List<SystemMainDto> findAllBySystemIdIn(List<String> systemIdList) {
        return SystemMainConverter.do2Dto(systemMainRepository.findAllBySystemIdIn(systemIdList));
    }

    public List<SystemMain> queryListByAuth(String account) {
        if (userService.userRoleContain(Constant.SYSTEM_ADMIN, account)) {
            return systemMainRepository.findAll();
        } else {
            return systemMainRepository.queryListByAuth(account);
        }
    }
//    /**
//     * 通过系统编号查找oa流程
//     */
//    public PageDto<VITSystemOAFlowResource> getOaFlowListBySystemClassNo(String systemClassNo, Integer pageNo, Integer pageSize){
//        OaflowResponse<PageDto<VITSystemOAFlowResource>> response = feignOaFlowService.getOaFlowListBySystemClassNo(pageNo, pageSize, systemClassNo);
//        return response.getData();
//    }

    /**
     * 通过系统编号查找platform侧关联流程
     * 先查找系统名称申请流程，再查系统名称变更流程，把两个列表组装进HashMap返回
     */
    public List<SystemFlowRelationResultDto> getFlowList(ParamFlowSearchDto params, String account) {
        final String APPLYFLOWTYPE = "系统名称申请";
        final String MODIFYFLOWTYPE = "系统名称变更";
        final String PLATFORM = "国联技术服务平台";
        final String OA = "OA";
        //查询自研网关关联流程
        Map<String, Object> param = new HashMap<>();
        //校验系统编号是否有权限
        List<SystemMain> systemMains = queryListByAuth(account);
        List<String> systemClassNoList = systemMains.stream().map(SystemMain::getSystemClassNo).collect(Collectors.toList());
        if (!systemClassNoList.contains(params.getSystemClassNo())) {
            throw PlatformException.error("非法的系统编号或无权限！");
        }
        param.put("EQ_systemClassNo", params.getSystemClassNo());
        if (StrUtil.isNotEmpty(params.getProcessTitle())) {
            param.put("LIKE_processTitle", params.getProcessTitle());
        }
        if (params.getBeginDate() != null) {
            param.put("GTE_processCreateTime", LocalDate.parse(params.getBeginDate()).atStartOfDay());
        }
        if (params.getEndDate() != null) {
            param.put("LTE_processCreateTime", LocalDate.parse(params.getEndDate()).atTime(23, 59, 59));
        }
//        ItDictData dictData = dictionaryService.findByDictData("am_flowable_processdefinekey");
//        Map<String, String> processTypeMap = Objects.nonNull(dictData)? dictData.getDictValues().stream().collect(Collectors.toMap(ItDict::getDictSubentry, o -> o.getDictValue())): new HashMap<>(0);
        List<FlowFormSystemNameApply> applyDoList = flowFormSystemNameApplyRepo.findAll(SpecificationUtil.buildSpecification(param, FlowFormSystemNameApply.class));
        List<FlowFormSystemNameModify> modifyDoList = flowFormSystemNameModifyRepo.findAll(SpecificationUtil.buildSpecification(param, FlowFormSystemNameModify.class));
        List<SystemFlowRelationResultDto> applyResultList = SystemFlowConverter.convertFromSNA(applyDoList);
        List<SystemFlowRelationResultDto> modifyResultList = SystemFlowConverter.convertFromSNM(modifyDoList);
        //查询oa关联流程
        OaflowResponse<List<VITSystemOAFlowResourceDto>> response = feignOaFlowService.getSystemOaFlowList(params);
        List<VITSystemOAFlowResourceDto> oaFlowList = response.getData();

        //根据索引生成唯一id
        AtomicReference<Integer> flowId = new AtomicReference<>(0);
        List<SystemFlowRelationResultDto> result = new ArrayList<>();

        //按照流程类型分组，处理数据成children嵌套格式
        if (CollectionUtil.isNotEmpty(applyResultList)) {
            SystemFlowRelationResultDto temp = new SystemFlowRelationResultDto();
            temp.setFlowId(flowId.getAndSet(flowId.get() + 1));
            temp.setProcessDefineKeyName(APPLYFLOWTYPE);
            temp.setFlowFrom(PLATFORM);
            temp.setChildren(
                    applyResultList.stream()
                            .map(h -> {
                                h.setProcessDefineKeyName(APPLYFLOWTYPE);
                                h.setFlowFrom(PLATFORM);
                                h.setFlowId(flowId.getAndSet(flowId.get() + 1));
                                return h;
                            })
                            .sorted(Comparator.comparing(SystemFlowRelationResultDto::getProcessCreateTime))
                            .collect(Collectors.toList())
            );
            result.add(temp);
        }
        if (CollectionUtil.isNotEmpty(modifyResultList)) {
            SystemFlowRelationResultDto temp = new SystemFlowRelationResultDto();
            temp.setFlowId(flowId.getAndSet(flowId.get() + 1));
            temp.setProcessDefineKeyName(MODIFYFLOWTYPE);
            temp.setFlowFrom(PLATFORM);
            temp.setChildren(
                    modifyResultList.stream()
                            .map(h -> {
                                h.setProcessDefineKeyName(MODIFYFLOWTYPE);
                                h.setFlowFrom(PLATFORM);
                                h.setFlowId(flowId.getAndSet(flowId.get() + 1));
                                return h;
                            })
                            .sorted(Comparator.comparing(SystemFlowRelationResultDto::getProcessCreateTime))
                            .collect(Collectors.toList()));
            result.add(temp);
        }
        HashMap<String, List<SystemFlowRelationResultDto>> oaFlowMap = new HashMap<>();
        for (VITSystemOAFlowResourceDto h : oaFlowList) {
            SystemFlowRelationResultDto temp = SystemFlowConverter.convertFromOAFlow(h);
            temp.setFlowId(flowId.getAndSet(flowId.get() + 1));
            temp.setFlowFrom(OA);
            List<SystemFlowRelationResultDto> dtoList = oaFlowMap.getOrDefault(temp.getProcessDefineKeyName(), new ArrayList<>());
            dtoList.add(temp);
            oaFlowMap.put(temp.getProcessDefineKeyName(), dtoList);
        }

        for (Map.Entry<String, List<SystemFlowRelationResultDto>> entry : oaFlowMap.entrySet()) {
            SystemFlowRelationResultDto temp = new SystemFlowRelationResultDto();
            temp.setFlowId(flowId.getAndSet(flowId.get() + 1));
            temp.setProcessDefineKeyName(entry.getKey());
            temp.setFlowFrom(OA);
            temp.setChildren(entry.getValue().stream().sorted(Comparator.comparing(SystemFlowRelationResultDto::getProcessCreateTime)).collect(Collectors.toList()));
            result.add(temp);
        }
        return result;
    }

    public byte[] exportSystemFlow(ParamFlowSearchDto params) throws IOException {
        //查询自研网关关联流程
        Map<String, Object> param = new HashMap<>();
        param.put("EQ_systemClassNo", params.getSystemClassNo());
        if (StrUtil.isNotEmpty(params.getProcessTitle())) {
            param.put("LIKE_processTitle", params.getProcessTitle());
        }
        if (params.getBeginDate() != null) {
            param.put("GTE_processCreateTime", LocalDate.parse(params.getBeginDate()).atStartOfDay());
        }
        if (params.getEndDate() != null) {
            param.put("LTE_processCreateTime", LocalDate.parse(params.getEndDate()).atTime(23, 59, 59));
        }
        List<FlowFormSystemNameApply> applyDoList = flowFormSystemNameApplyRepo.findAll(SpecificationUtil.buildSpecification(param, FlowFormSystemNameApply.class));
        List<FlowFormSystemNameModify> modifyDoList = flowFormSystemNameModifyRepo.findAll(SpecificationUtil.buildSpecification(param, FlowFormSystemNameModify.class));
        //查询oa关联流程
        OaflowResponse<List<VITSystemOAFlowResourceDto>> response = feignOaFlowService.getSystemOaFlowList(params);
        List<VITSystemOAFlowResourceDto> oaFlowList = response.getData();

        ArrayList<SystemFlowRelationResultDto> result = new ArrayList<>();
        List<SystemFlowRelationResultDto> applyResultList = SystemFlowConverter.convertFromSNA(applyDoList).stream().sorted(Comparator.comparing(SystemFlowRelationResultDto::getProcessCreateTime)).collect(Collectors.toList());
        List<SystemFlowRelationResultDto> modifyResultList = SystemFlowConverter.convertFromSNM(modifyDoList).stream().sorted(Comparator.comparing(SystemFlowRelationResultDto::getProcessCreateTime)).collect(Collectors.toList());
        List<SystemFlowRelationResultDto> systemFlowRelationResultDtos = SystemFlowConverter.convertFromOAFlow(oaFlowList).stream().sorted(Comparator.comparing(SystemFlowRelationResultDto::getProcessCreateTime)).collect(Collectors.toList());
        result.addAll(applyResultList);
        result.addAll(modifyResultList);
        result.addAll(systemFlowRelationResultDtos);
        return ExportFileUtil.export(result, ExportFileEnum.SYSTEM_RELATION_FLOW);
    }

    public PlatformResponse<SystemFlowStatisticsVo> countSystemFlowStatistics(SystemFlowStatisticsSearchParamDto params, String account) throws Exception {
        if (Strings.isNotBlank(params.getBelongDeptId())) {
            LdapResponse<List<LdapEhrDeptDto>> allDeptResp = iFeignLdapService.getDepartmentList(
                    LdapEhrDeptSearchDto.builder()
                            .compTitleOrDepId(params.getBelongDeptId())
                            .build()
            );
            List<String> belongDeptIdList = Objects.isNull(allDeptResp) || CollectionUtil.isEmpty(allDeptResp.getData()) ?
                    List.of(params.getBelongDeptId()) :
                    allDeptResp.getData().stream().map(d -> String.valueOf(d.getDepid())).collect(Collectors.toList());
            params.setBelongDeptIdList(belongDeptIdList);
        }
        if (Strings.isNotBlank(params.getOpGroupId())) {
            LdapResponse<List<LdapEhrDeptDto>> allDeptResp = iFeignLdapService.getDepartmentList(
                    LdapEhrDeptSearchDto.builder()
                            .compTitleOrDepId(params.getOpGroupId())
                            .build()
            );
            List<String> allQueryDepIds = Objects.isNull(allDeptResp) || CollectionUtil.isEmpty(allDeptResp.getData()) ?
                    Collections.singletonList(params.getOpGroupId()) :
                    allDeptResp.getData().stream().map(d -> String.valueOf(d.getDepid())).collect(Collectors.toList());
            params.setOpGroupIdList(allQueryDepIds);
        }
        //未经权限筛选的全部系统
        List<SystemMain> systemMains = systemMainRepository.queryByParam(params);
        Map<String, String> systemDictMap = systemMains.stream().collect(Collectors.toMap(SystemMain::getSystemClassNo, SystemMain::getOpName, (value1, value2) -> value1));

        Set<String> systemClassNoList = systemDictMap.keySet();
        if (!userService.userRoleContain(Constant.SYSTEM_ADMIN, account) && (params.getSystemClassNoList() == null || params.getSystemClassNoList().size() == 0)) {
            //有权限查看的系统。如果前端传的参数直接是系统编号，跳过这一步
            Set<String> authList = systemMainRepository.queryListByAuth(account).stream().map(SystemMain::getSystemClassNo).collect(Collectors.toSet());
            systemClassNoList = systemClassNoList.stream().filter(authList::contains).collect(Collectors.toSet());

        }
        if (systemClassNoList.size() == 0) {
            return PlatformResponse.failedMsg("未匹配到有效系统！");
        }
        params.setSystemClassNoList(systemClassNoList);
        OaflowResponse<SystemFlowStatisticsDto> oaFlowStatistics = feignOaFlowService.getOAFlowStatistics(params);
        SystemFlowStatisticsDto data = oaFlowStatistics.getData();

        SystemFlowStatisticsVo systemFlowStatisticsVo = SystemFlowStatisticsConverter.dto2vo(data, systemDictMap, systemClassNoList.size());
        systemFlowStatisticsVo.setCurrentSystemNameList(systemClassNoList.stream().map(h -> systemDictMap.get(h)).collect(Collectors.toList()));
        return PlatformResponse.successData(systemFlowStatisticsVo);
    }

    private static List<String> bfsGetAllDept(String opGroupId, Map<String, List<LdapEhrDept>> parentDepMap) {
        List<String> allQueryDepIds = new ArrayList<>();
        //bfs遍历选择部门下所有部门id
        Queue<String> que = new LinkedList<>();
        que.add(opGroupId);
        while (!que.isEmpty()) {
            String depId = que.poll();
            allQueryDepIds.add(depId);
            if (parentDepMap.containsKey(depId)) {
                List<LdapEhrDept> children = parentDepMap.get(depId);
                que.addAll(children.stream().map(d -> String.valueOf(d.getDepid())).collect(Collectors.toList()));
            }
        }
        return allQueryDepIds;
    }

    public List<SystemMain> query(SystemFlowStatisticsSearchParamDto param) {
        return systemMainRepository.queryByParam(param);
    }

    /**
     * 获取全部ip和systemcode的关系
     *
     * @return
     */
    public List<IpSystemCode> queryIpSystemCode() {
        return iPSystemCodeRepository.findAll();
    }

    /**
     * 查询系统标识不为空的系统列表
     */
    public List<SystemMainDto> findAllBySystemIdNotNull() {
        List<SystemMain> systemMainList = systemMainRepository.findAllBySystemIdNotNull().stream().filter(item -> StrUtil.isNotEmpty(item.getSystemId())).collect(Collectors.toList());
        return SystemMainConverter.do2Dto(systemMainList);
    }

    public List<SystemMainDto> findAllByProgramIdNotNull() {
        List<SystemMain> systemMainList = systemMainRepository.findAllByProgramIdNotNull().stream().filter(item -> StrUtil.isNotEmpty(item.getProgramId())).collect(Collectors.toList());
        return SystemMainConverter.do2Dto(systemMainList);
    }
}
